package com.dragon.annotation;

import javax.persistence.Table;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 默认的persistence包扫描器
 *
 * @author dragon
 * @since 2019/11/12
 */
public class DefaultPackageScanner implements PackageScanner {

    /**
     * 读取java配置文件，扫描包
     *
     * @param annotatedClasses 配置文件信息
     * @return java.util.List<java.lang.Class>
     * @throws ClassNotFoundException 类找不到异常
     */
    @Override
    public List<Class<?>> scanPackage(Class<?> annotatedClasses) throws ClassNotFoundException {
        if (annotatedClasses == null) {
            return null;
        }
        EntityScan entityScanAnnotation = annotatedClasses.getDeclaredAnnotation(EntityScan.class);
        String[] basePackages = entityScanAnnotation.basePackages();
        if (basePackages.length == 0) {
            return null;
        }
        ArrayList<Class<?>> resultList = new ArrayList<>();
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        for (String basePackage : basePackages) {
            URL basePackageUrl = contextClassLoader.getResource(basePackage.replace(".", "/"));
            if (basePackageUrl == null) {
                continue;
            }
            File file = new File(basePackageUrl.getFile());
            if (file.isDirectory()) {
                doScanPackage(basePackage, file, resultList);
            }
        }

        return resultList;
    }

    /**
     * 扫描包，将带有@Table注释的类的class文件找出来
     *
     * @param basePackage 基础的包
     * @param currentFile 当前的文件目录
     * @param list        结果集
     * @throws ClassNotFoundException 类找不到异常
     */
    private void doScanPackage(String basePackage, File currentFile, List<Class<?>> list)
            throws ClassNotFoundException {
        // 筛选文件夹或者已后缀名.class结尾的文件
        File[] files = currentFile.listFiles(file -> {
            if (file.isDirectory()) {
                return true;
            }
            return file.getName().endsWith(".class");
        });
        if (files != null && files.length != 0) {
            for (File file : files) {
                if (file.isDirectory()) {
                    doScanPackage(basePackage.concat(".").concat(file.getName()), file, list);
                }
                String fileName = file.getName();
                Class<?> entityClazz = Class.forName(basePackage.concat(".").concat(fileName.substring(0,
                        fileName.lastIndexOf("."))));
                if (entityClazz.isAnnotation() || entityClazz.isEnum() || entityClazz.isInterface()) {
                    continue;
                }
                if (entityClazz.isAnnotationPresent(Table.class)) {
                    list.add(entityClazz);
                }
            }
        }

    }
}
